﻿//-----------------------------------------------------------------------
// <copyright file="UISettingsDataHelper.cs" company="AFS">
// Copyright (c) AFS. All rights reserved.
//
//    This file is part of Chatbox.
//
//    Chatbox is free software: you can redistribute it and/or modify
//    it under the terms of the GNU Lesser General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    any later version.
//
//    Chatbox is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//    GNU Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public License
//    along with Chatbox. If not, see http://www.gnu.org/copyleft/lesser.html
// </copyright>
//----------------------------------------------------------------------- 

namespace ChatBox.DomainObjects.Settings
{
    using System.IO;
    using System.Windows;
    using System.Xml.Serialization;

    /// <summary>
    /// class for helper methods on settings data
    /// </summary>
    public static class UISettingsDataHelper
    {
        #region data

        /// <summary>
        /// Default value for the Ui theme
        /// </summary>
        public const string DefaultTheme = "Blue";

        /// <summary>
        /// Default value for the public messages font size
        /// </summary>
        public const int DefaultPublicMessageFontSize = 16;

        /// <summary>
        /// Default value for the other usres font size
        /// </summary>
        public const int DefaultOtherUsersFontSize = 15;
        
        /// <summary>
        /// Default value for the topic font size
        /// </summary>
        public const int DefaultTopicFontSize = 17;

        /// <summary>
        /// Default value for the private messages font size
        /// </summary>
        public const int DefaultPrivateMessageFontSize = 16;

        /// <summary>
        /// Default value for the popup notification window font size
        /// </summary>
        public const int DefaultNotificationFontSize = 14;

        /// <summary>
        /// Default value for the tooltip font size
        /// </summary>
        public const int DefaultTooltipFontSize = 12;

        /// <summary>
        /// Default value for the speak font size
        /// </summary>
        public const int DefaultSpeakFontSize = 13;

        /// <summary>
        /// Default value for the Max Private Messages Shown
        /// </summary>
        public const int DefaultMaxPrivateMessagesShown = 200;

        /// <summary>
        /// Min value for the Max Private Messages Shown
        /// </summary>
        public const int MinMaxPrivateMessagesShown = 100;

        /// <summary>
        /// Max value for the Max Private Messages Shown
        /// </summary>
        public const int MaxMaxPrivateMessagesShown = 1000;

        /// <summary>
        /// single instance of the xml serializer for Ui SettingsData
        /// </summary>
        private static XmlSerializer uiSettingsDataSerializer;

        #endregion

        #region public

        /// <summary>
        /// generate default Ui settings containing the expected values
        /// </summary>
        /// <returns>the default Ui settings</returns>       
        public static UISettingsData Default()
        {
            return new UISettingsData
            {
                Theme = DefaultTheme,
                ShowTopic = true,
                ShowSpeak = true,
                ShowThrobber = true,
                ShowOtherUsers = true,
                NotifyOfNewVersionAvailable = true,
                MainWindowDimensions = new Rect(0, 0, 0, 0),
                PrivateMessagesWindowDimensions = new Rect(0, 0, 0, 0),
                TickersWindowDimensions = new Rect(0, 0, 0, 0),
                PlaySoundOnNewPublicMessage = false,
                PlaySoundOnError = true,
                PlaySoundOnNewPrivateMessage = true,
                PopupWindowOnNewPrivateMessage = true,
                InlineNewPrivateMessage = true,
                MaxPrivateMessagesShown = DefaultMaxPrivateMessagesShown,
                PublicMessageFontSize = DefaultPublicMessageFontSize,
                PrivateMessageFontSize = DefaultPrivateMessageFontSize,
                OtherUsersFontSize = DefaultOtherUsersFontSize,
                TopicFontSize = DefaultTopicFontSize,
                TooltipFontSize = DefaultTooltipFontSize,
                NotificationFontSize = DefaultNotificationFontSize,
                SpeakFontSize = DefaultSpeakFontSize,
                ShowSendPrivateMessageButtonInPublicChat = false,
                ShowSendPrivateMessageButtonInPrivateMessages = true,
                ShowSendPrivateMessageButtonInOtherUsers = true,
                UseBuiltInSpellchecker = true,
                ShowDeleteMessageButtonInPrivateMessages = true,
                SettingsTabIndex = 0
            };
        }

        /// <summary>
        /// Rsplace missing values in the settings with defaults
        /// </summary>
        /// <param name="uiSettings">the settings data to work with</param>       
        public static void ReplaceEmptySettingsWithDefaults(UISettingsData uiSettings)
        {
            if (string.IsNullOrEmpty(uiSettings.Theme))
            {
                uiSettings.Theme = DefaultTheme;
            }

            if (uiSettings.MaxPrivateMessagesShown == 0)
            {
                uiSettings.MaxPrivateMessagesShown = DefaultMaxPrivateMessagesShown;
            }

            if (uiSettings.MaxPrivateMessagesShown > MaxMaxPrivateMessagesShown)
            {
                uiSettings.MaxPrivateMessagesShown = MaxMaxPrivateMessagesShown;
            }

            if (uiSettings.MaxPrivateMessagesShown < MinMaxPrivateMessagesShown)
            {
                uiSettings.MaxPrivateMessagesShown = MinMaxPrivateMessagesShown;
            }

            if (uiSettings.PublicMessageFontSize == 0)
            {
                uiSettings.PublicMessageFontSize = DefaultPublicMessageFontSize;
            }

            if (uiSettings.PrivateMessageFontSize == 0)
            {
                uiSettings.PrivateMessageFontSize = DefaultPrivateMessageFontSize;
            }

            if (uiSettings.TooltipFontSize == 0)
            {
                uiSettings.TooltipFontSize = DefaultTooltipFontSize;
            }

            if (uiSettings.TopicFontSize == 0)
            {
                uiSettings.TopicFontSize = DefaultTopicFontSize;
            }

            if (uiSettings.NotificationFontSize == 0)
            {
                uiSettings.NotificationFontSize = DefaultNotificationFontSize;
            }

            if (uiSettings.SpeakFontSize == 0)
            {
                uiSettings.SpeakFontSize = DefaultSpeakFontSize;
            }

            if (uiSettings.OtherUsersFontSize == 0)
            {
                uiSettings.OtherUsersFontSize = DefaultOtherUsersFontSize;
            }

            if ((uiSettings.SettingsTabIndex < 0) || (uiSettings.SettingsTabIndex > 2))
            {
                uiSettings.SettingsTabIndex = 0;
            }
        }

        /// <summary>
        /// Read setttings data from a stream
        /// </summary>
        /// <param name="stream">the stream to read from</param>
        /// <returns>The data read</returns>
        public static UISettingsData ReadFromStream(Stream stream)
        {
            XmlSerializer ser = GetDataSerializer();
            return (UISettingsData)ser.Deserialize(stream);
        }

        /// <summary>
        /// Write settings data to a stream
        /// </summary>
        /// <param name="data">the data to write</param>
        /// <param name="stream">the stream to write it to</param>
        public static void WriteToStream(UISettingsData data, Stream stream)
        {
            XmlSerializer ser = GetDataSerializer();
            ser.Serialize(stream, data);
        }

        /// <summary>
        /// Make a copy of the settings data
        /// </summary>
        /// <param name="data">the data to copy</param>
        /// <returns>a copy of the data</returns>
        public static UISettingsData Copy(this UISettingsData data)
        {
            return new UISettingsData
            {
                Theme = data.Theme,
                ShowTopic = data.ShowTopic,
                ShowSpeak = data.ShowSpeak,
                ShowThrobber = data.ShowThrobber,
                ShowOtherUsers = data.ShowOtherUsers,
                NotifyOfNewVersionAvailable = data.NotifyOfNewVersionAvailable,

                PlaySoundOnNewPublicMessage = data.PlaySoundOnNewPublicMessage,
                PlaySoundOnError = data.PlaySoundOnError,
                PlaySoundOnNewPrivateMessage = data.PlaySoundOnNewPrivateMessage,
                MaxPrivateMessagesShown = data.MaxPrivateMessagesShown,

                MainWindowDimensions = data.MainWindowDimensions,
                PrivateMessagesWindowDimensions = data.PrivateMessagesWindowDimensions,
                TickersWindowDimensions = data.TickersWindowDimensions,

                PopupWindowOnNewPrivateMessage = data.PopupWindowOnNewPrivateMessage,
                InlineNewPrivateMessage = data.InlineNewPrivateMessage,
                PublicMessageFontSize = data.PublicMessageFontSize,
                PrivateMessageFontSize = data.PrivateMessageFontSize,
                TooltipFontSize = data.TooltipFontSize,
                TopicFontSize = data.TopicFontSize,
                NotificationFontSize = data.NotificationFontSize,
                SpeakFontSize = data.SpeakFontSize,
                OtherUsersFontSize = data.OtherUsersFontSize,

                ShowSendPrivateMessageButtonInPublicChat = data.ShowSendPrivateMessageButtonInPublicChat,
                ShowSendPrivateMessageButtonInPrivateMessages = data.ShowSendPrivateMessageButtonInPrivateMessages,
                ShowSendPrivateMessageButtonInOtherUsers = data.ShowSendPrivateMessageButtonInOtherUsers,
            
                UseBuiltInSpellchecker = data.UseBuiltInSpellchecker,
                ShowDeleteMessageButtonInPrivateMessages = data.ShowDeleteMessageButtonInPrivateMessages,
                SettingsTabIndex = data.SettingsTabIndex
            };
        }

        /// <summary>
        /// Do the two settings contain the same values?
        /// </summary>
        /// <param name="data1">the first UI settings</param>
        /// <param name="data2">the second UI settings</param>
        /// <returns>true if they contain the same data</returns>    
        public static bool SettingsSame(UISettingsData data1, UISettingsData data2)
        {
            if (!SettingsShowFlagsSame(data1, data2))
            {
                return false;
            }

            if (data1.Theme != data2.Theme)
            {
                return false;
            }

            if (data1.NotifyOfNewVersionAvailable != data2.NotifyOfNewVersionAvailable)
            {
                return false;
            } 
            
            if (data1.MainWindowDimensions != data2.MainWindowDimensions)
            {
                return false;
            }

            if (data1.PrivateMessagesWindowDimensions != data2.PrivateMessagesWindowDimensions)
            {
                return false;
            }

            if (data1.TickersWindowDimensions != data2.TickersWindowDimensions)
            {
                return false;
            }
            
            if (data1.PlaySoundOnNewPublicMessage != data2.PlaySoundOnNewPublicMessage)
            {
                return false;
            }

            if (data1.PlaySoundOnError != data2.PlaySoundOnError)
            {
                return false;
            }

            if (data1.PlaySoundOnNewPrivateMessage != data2.PlaySoundOnNewPrivateMessage)
            {
                return false;
            }

            if (data1.PopupWindowOnNewPrivateMessage != data2.PopupWindowOnNewPrivateMessage)
            {
                return false;
            }

            if (data1.InlineNewPrivateMessage != data2.InlineNewPrivateMessage)
            {
                return false;
            }

            if (data1.MaxPrivateMessagesShown != data2.MaxPrivateMessagesShown)
            {
                return false;
            }

            if (!FontSizesSame(data1, data2))
            {
                return false;
            }

            if (data1.UseBuiltInSpellchecker != data2.UseBuiltInSpellchecker)
            {
                return false;
            }

            if (data1.ShowDeleteMessageButtonInPrivateMessages != data2.ShowDeleteMessageButtonInPrivateMessages)
            {
                return false;
            }

            if (data1.SettingsTabIndex != data2.SettingsTabIndex)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// Do the two settings contain the same font size values?
        /// </summary>
        /// <param name="data1">the first UI settings</param>
        /// <param name="data2">the second UI settings</param>
        /// <returns>true if they contain the same data</returns> 
        private static bool FontSizesSame(UISettingsData data1, UISettingsData data2)
        {
            if (data1.PublicMessageFontSize != data2.PublicMessageFontSize)
            {
                return false;
            }

            if (data1.TopicFontSize != data2.TopicFontSize)
            {
                return false;
            }

            if (data1.PrivateMessageFontSize != data2.PrivateMessageFontSize)
            {
                return false;
            }

            if (data1.NotificationFontSize != data2.NotificationFontSize)
            {
                return false;
            }

            if (data1.TooltipFontSize != data2.TooltipFontSize)
            {
                return false;
            }

            if (data1.SpeakFontSize != data2.SpeakFontSize)
            {
                return false;
            }

            if (data1.OtherUsersFontSize != data2.OtherUsersFontSize)
            {
                return false;
            }

            if (data1.ShowSendPrivateMessageButtonInPublicChat != data2.ShowSendPrivateMessageButtonInPublicChat)
            {
                return false;
            }

            if (data1.ShowSendPrivateMessageButtonInPrivateMessages != data2.ShowSendPrivateMessageButtonInPrivateMessages)
            {
                return false;
            }

            if (data1.ShowSendPrivateMessageButtonInOtherUsers != data2.ShowSendPrivateMessageButtonInOtherUsers)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// Do the two settings flags contain the same values?
        /// </summary>
        /// <param name="data1">the first UI settings</param>
        /// <param name="data2">the second UI settings</param>
        /// <returns>true if they contain the same data</returns>    
        private static bool SettingsShowFlagsSame(UISettingsData data1, UISettingsData data2)
        {
            if (data1.ShowTopic != data2.ShowTopic)
            {
                return false;
            }

            if (data1.ShowSpeak != data2.ShowSpeak)
            {
                return false;
            }

            if (data1.ShowThrobber != data2.ShowThrobber)
            {
                return false;
            }

            if (data1.ShowOtherUsers != data2.ShowOtherUsers)
            {
                return false;
            }

            return true;
        }

        #endregion

        #region private

        /// <summary>
        /// Get the XML serialiser for chat settings
        /// </summary>
        /// <returns>the xml serializer</returns>
        private static XmlSerializer GetDataSerializer()
        {
            if (uiSettingsDataSerializer == null)
            {
                uiSettingsDataSerializer = new XmlSerializer(typeof(UISettingsData));
            }

            return uiSettingsDataSerializer;
        }

        #endregion
    }
}
